module sw.global.defaultcommands;

import sw.commands, sw.parser, sw.siteconfig, nazo.http, nazo.string, std.stdio, std.contracts;
///標準コマンド
class DefaultCommands:Commands{
  const static string prefix="";
  string value(SiteConfig* cfg,string name,string[] args,Cmd* cmd,uint hierarchy,string path){
    switch(args.length){
      case 1:
        switch(name){
          case "sec":
            char i=cast(char)(hierarchy+'0'); // FIXME: if hierarchy > 9
            Cmd* c=cmd;
            while(c.parent !is null){
              c=c.parent;
              if(c.name=="sec")i++;
            }
            char tc=i;
            char[] t="<div class=\"section\" id=\"id_\0\0\0\0\0\0\">\n<h\0>".dup;
            t["<div class=\"section\" id=\"id_".length.."<div class=\"section\" id=\"id_".length+6]=ArgConv.getID(args[0])[0..6];
            t[$-2]=tc;
            return assumeUnique(t)~args[0]~"</h"~tc~">\n<div class=\"about\">"~args[0]~"\n</div>\n</div>";
          case "p":
            return "<p>"~args[0] ~"</p>";
          case "l":
            return args[0] ~"<br/>";
          case "ul":
            return "<ul>"~args[0] ~"</ul>";
          case "ol":
            return "<ol>"~args[0] ~"</ol>";
          case "li":
            return "<li>"~args[0] ~"</li>";
          case "a":
            return "<a href=\""~ArgConv.hrefTargetEscape(args[0] )~"\">"~args[0] ~"</a>";
          case "em":
            return "<em>"~args[0] ~"</em>";
          case "strong":
            return "<strong>"~args[0] ~"</strong>";
          case "dl":
            return "<dl>"~args[0] ~"</dl>";
          case "dt":
            return "<dt>"~args[0] ~"</dt>";
          case "dd":
            return "<dd>"~args[0] ~"</dd>";
          case "table":
            return "<table>"~args[0] ~"</table>";
          case "tr":
            return "<tr>"~args[0] ~"</tr>";
          case "td":
            return "<td>"~args[0] ~"</td>";
          case "th":
            return "<th>"~args[0] ~"</th>";
          case "code":
            return "<code>"~args[0] ~"</code>";
          case "blockcode":
            return "<pre><code>"~args[0] ~"</code></pre>";
          case "dfn":
            return "<dfn>"~args[0] ~"</dfn>";
          case "ruby":
            return "<ruby>"~args[0] ~"</ruby>";
          case "rbc":
            return "<rbc>"~args[0] ~"</rbc>";
          case "rtc":
            return "<rtc>"~args[0] ~"</rtc>";
          case "rb":
            return "<rb>"~args[0] ~"</rb>";
          case "rt":
            return "<rt>"~args[0] ~"</rt>";
          case "rp":
            return "<rp>"~args[0] ~"</rp>";
          case "obj":
            return "<object data=\""~ArgConv.srcTargetEscape(args[0] )~"\"></object>";
          case "kbd":
            return "<kbd>"~args[0] ~"</kbd>";
          case "q":
            return "<q>"~args[0] ~"</q>";
          case "samp":
            return "<samp>"~args[0] ~"</samp>";
          case "var":
            return "<var>"~args[0] ~"</var>";
          case "blockquote":
            return "<blockquote>"~args[0] ~"</blockquote>";
          case "rem":
            return "";
          case "pre":
            return "<pre>"~args[0] ~"</pre>";
          default:
        }
        break;
      case 2:
        switch(name){
          case "sec":
            char i=cast(char)(hierarchy+'0'); // FIXME: if hierarchy > 9
            Cmd* c=cmd;
            while(c.parent !is null){
              c=c.parent;
              if(c.name=="sec")i++;
            }
            char tc=i;
            char[] t="<div class=\"section\" id=\"id_\0\0\0\0\0\0\">\n<h\0>".dup;
            t["<div class=\"section\" id=\"id_".length.."<div class=\"section\" id=\"id_".length+6]=ArgConv.getID(args[0])[0..6];
            t[$-2]=tc;
            return assumeUnique(t)~args[0]~"</h"~tc~">\n<div class=\"about\">"~args[1]~"\n</div>\n</div>";
          case "li":
            return "<li><a href=\""~ArgConv.hrefTargetEscape(args[1] )~"\">"~args[0] ~"</a></li>";
          case "a":
            return "<a href=\""~ArgConv.hrefTargetEscape(args[1] )~"\">"~args[0] ~"</a>";
          case "table":
            return "<table>\n<caption>"~args[0] ~"</caption>"~args[1] ~"\n</table>";
          case "obj":
            return "<object data=\""~ArgConv.srcTargetEscape(args[0] )~"\" type=\""~ArgConv.attrEscape(args[1] )~"\"></object>";
          case "abbr":
            return "<abbr title=\""~ArgConv.attrEscape(args[1] )~"\">"~args[0] ~"</abbr>";
          case "acronym":
            return "<acronym title=\""~ArgConv.attrEscape(args[1] )~"\">"~args[0] ~"</acronym>";
          case "q":
            return "<q title=\""~ArgConv.attrEscape(args[1] )~"\">"~args[0] ~"</q>";
          case "blockquote":
            return "<blockquote title=\""~ArgConv.attrEscape(args[1] )~"\">"~args[0] ~"</blockquote>";
          default:
        }
        break;
      case 3:
        switch(name){
          case "obj":
            return "<object data=\""~ArgConv.srcTargetEscape(args[0] )~"\" type=\""~ArgConv.attrEscape(args[1] )~"\">"~args[2] ~"</object>";
          case "q":
            return "<q title=\""~ArgConv.attrEscape(args[1] )~"\" cite=\""~ArgConv.hrefTargetEscape(args[2] )~"\">"~args[0] ~"</q>";
          case "blockquote":
            return "<blockquote title=\""~ArgConv.attrEscape(args[1] )~"\" cite=\""~ArgConv.hrefTargetEscape(args[2] )~"\">"~args[0] ~"</blockquote>";
          default:
        }
        break;
      default:
    }

/+    switch(name){
      case "sec":
        uint i=hierarchy;
        Cmd* c=cmd;
        while(c.parent !is null){
          c=c.parent;
          if(c.name=="sec")i++;
        }
        char tc=i+'0';
        if(args.length==1 || args.length==2){
          string t="<div class=\"section\" id=\"id_\0\0\0\0\0\0\">\n<h\0>".dup;
          t["<div class=\"section\" id=\"id_".length.."<div class=\"section\" id=\"id_".length+6]=ArgConv.getID(args[0])[0..$];
          t[$-2]=tc;
          if(args.length==1) return t~args[0]~"</h"~tc~">\n<div class=\"about\">"~args[0]~"\n</div>\n</div>";
          else return t~args[0]~"</h"~tc~">\n<div class=\"about\">"~args[1]~"\n</div>\n</div>";
        }

/+        string si;
        si.length=2;
        si[0]=i+'0';
        si[1]='>';
/+        //* [sec title] セクション。XHTML2のsection要素+h要素と同じ
        if(args.length==1)return "<div class=\"section\" id=\"id_"~ArgConv.getID(args[0])~"\">\n<h"~si~args[0]~"</h"~si~"</div>";
        //* [sec title,contents] セクション。XHTML2のsection要素+h要素と同じ
        if(args.length==2)return "<div class=\"section\" id=\"id_"~ArgConv.getID(args[0])~"\">\n<h"~si~args[0]~"</h"~si~"\n<div class=\"about\">"~args[1]~"\n</div>\n</div>";+/
        if(args.length==1){
          string t;
          string t2=ArgConv.getID(args[0]);
          t.length="<div class=\"section\" id=\"id_".length+"\">\n<h".length+"</h".length+"</div>".length+args[0].length+t2.length+si.length*2;
          t[0..$]="<div class=\"section\" id=\"id_"~ArgConv.getID(args[0])~"\">\n<h"~si~args[0]~"</h"~si~"</div>";
          return t;
        }
        if(args.length==2){
          string t;
          string t2=ArgConv.getID(args[0]);
          t.length="<div class=\"section\" id=\"id_".length+"\">\n<h".length+"</h".length+"\n<div class=\"about\">".length+"\n</div>\n</div>".length+args[0].length+args[1].length+t2.length+si.length*2;
          t[0..$]="<div class=\"section\" id=\"id_"~ArgConv.getID(args[0])~"\">\n<h"~si~args[0]~"</h"~si~"\n<div class=\"about\">"~args[1]~"\n</div>\n</div>";
          return t;
        }+/
        break;
      case "p":
        //* [p content] 段落。XHTML1.1のpと同じ
        if(args.length==1)return "<p>"~args[0] ~"</p>";
        break;
      case "l":
        //* [l content] line。XHTML2のl要素と同じ
        if(args.length==1)return args[0] ~"<br/>";
        break;
      case "ul":
        //* [ul lists] 順不同リスト。XHTML1.1のulと同じ
        if(args.length==1)return "<ul>"~args[0] ~"</ul>";
        break;
      case "ol":
        //* [ol lists] 順序付きリスト。XHTML1.1のolと同じ
        if(args.length==1)return "<ol>"~args[0] ~"</ol>";
        break;
      case "li":
        //* [li content] リストの項目。XHTML1.1のliと同じ
        if(args.length==1)return "<li>"~args[0] ~"</li>";
        //* [li content,url] リストの項目。XHTML2のli hrefと同じ
        if(args.length==2)return "<li><a href=\""~ArgConv.hrefTargetEscape(args[1] )~"\">"~args[0] ~"</a></li>";
        break;
      case "a":
        //* [a uri] リンク
        if(args.length==1)return "<a href=\""~ArgConv.hrefTargetEscape(args[0] )~"\">"~args[0] ~"</a>";
        //* [a title,uri] リンク
        if(args.length==2)return "<a href=\""~ArgConv.hrefTargetEscape(args[1] )~"\">"~args[0] ~"</a>";
        break;
      case "em":
        //* [em content] 強調。XHTML1.1のemと同じ
        if(args.length==1)return "<em>"~args[0] ~"</em>";
        break;
      case "strong":
        //* [strong content] もっと強調。XHTML1.1のstrongと同じ
        if(args.length==1)return "<strong>"~args[0] ~"</strong>";
        break;
      case "dl":
        //* [dl lists] 定義リスト。XHTML1.1のdlと同じ
        if(args.length==1)return "<dl>"~args[0] ~"</dl>";
        break;
      case "dt":
        //* [dt content] 定義する名前。XHTML1.1のdtと同じ
        if(args.length==1)return "<dt>"~args[0] ~"</dt>";
        break;
      case "dd":
        //* [dd contents] 定義する内容。XHTML1.1のddと同じ
        if(args.length==1)return "<dd>"~args[0] ~"</dd>";
        break;
      case "table":
        //* [table trs] 表。XHTML1.1のtableと同じ
        if(args.length==1)return "<table>"~args[0] ~"</table>";
        //* [table caption,trs] 表。XHTML1.1のtable要素+caption要素と同じ
        if(args.length==2)return "<table>\n<caption>"~args[0] ~"</caption>"~args[1] ~"\n</table>";
        break;
      case "tr":
        //* [tr tds] 列。XHTML1.1のtrと同じ
        if(args.length==1)return "<tr>"~args[0] ~"</tr>";
        break;
      case "td":
        //* [td content] セル。XHTML1.1のtdと同じ
        if(args.length==1)return "<td>"~args[0] ~"</td>";
        break;
      case "th":
        //* [th content] タイトルなセル。XHTML1.1のthと同じ
        if(args.length==1)return "<th>"~args[0] ~"</th>";
        break;
      case "code":
        //* [code content] コード。XHTML1.1のcodeと同じ
        if(args.length==1)return "<code>"~args[0] ~"</code>";
        break;
      case "blockcode":
        //* [blockcode contents] コードブロック。XHTML2のblockcodeと同じ
        if(args.length==1)return "<pre><code>"~args[0] ~"</code></pre>";
        break;
      case "dfn":
        //* [dfn content] dfn。XHTML1.1のdfnと同じ
        if(args.length==1)return "<dfn>"~args[0] ~"</dfn>";
        break;
      case "ruby":
        //* [ruby ruby] ruby。XHTML1.1のrubyと同じ
        if(args.length==1)return "<ruby>"~args[0] ~"</ruby>";
        break;
      case "rbc":
        //* [rbc content] rbc。XHTML1.1のrbcと同じ
        if(args.length==1)return "<rbc>"~args[0] ~"</rbc>";
        break;
      case "rtc":
        //* [rtc content] rtc。XHTML1.1のrtcと同じ
        if(args.length==1)return "<rtc>"~args[0] ~"</rtc>";
        break;
      case "rb":
        //* [rb content] rb。XHTML1.1のrbと同じ
        if(args.length==1)return "<rb>"~args[0] ~"</rb>";
        break;
      case "rt":
        //* [rt content] rt。XHTML1.1のrtと同じ
        if(args.length==1)return "<rt>"~args[0] ~"</rt>";
        break;
      case "rp":
        //* [rp content] rp。XHTML1.1のrpと同じ
        if(args.length==1)return "<rp>"~args[0] ~"</rp>";
        break;
      case "obj":
        //* [obj uri] オブジェクト。XHTML1.1のobjectと同じ
        if(args.length==1)return "<object data=\""~ArgConv.srcTargetEscape(args[0] )~"\"></object>";
        //* [obj uri,type] オブジェクト。XHTML1.1のobjectと同じ
        if(args.length==2)return "<object data=\""~ArgConv.srcTargetEscape(args[0] )~"\" type=\""~ArgConv.attrEscape(args[1] )~"\"></object>";
        //* [obj uri,type,altContents] オブジェクト。XHTML1.1のobjectと同じ
        if(args.length==3)return "<object data=\""~ArgConv.srcTargetEscape(args[0] )~"\" type=\""~ArgConv.attrEscape(args[1] )~"\">"~args[2] ~"</object>";
        break;
      case "addr":
        //* [abbr title,content] abbr。XHTML1.1のabbrと同じ
        if(args.length==2)return "<abbr title=\""~ArgConv.attrEscape(args[1] )~"\">"~args[0] ~"</abbr>";
        break;
      case "acronym":
        //* [acronym title,content] acronym。XHTML1.1のacronymと同じ
        if(args.length==2)return "<acronym title=\""~ArgConv.attrEscape(args[1] )~"\">"~args[0] ~"</acronym>";
        break;
      case "kbd":
        //* [kbd content] キーボード。XHTML1.1のkbdと同じ
        if(args.length==1)return "<kbd>"~args[0] ~"</kbd>";
        break;
      case "q":
        //* [q content] 引用。XHTML1.1のqと同じ
        if(args.length==1)return "<q>"~args[0] ~"</q>";
        //* [q content,title] 引用。XHTML1.1のqと同じ
        if(args.length==2)return "<q title=\""~ArgConv.attrEscape(args[1] )~"\">"~args[0] ~"</q>";
        //* [q content,title,uri] 引用。XHTML1.1のqと同じ
        if(args.length==3)return "<q title=\""~ArgConv.attrEscape(args[1] )~"\" cite=\""~ArgConv.hrefTargetEscape(args[2] )~"\">"~args[0] ~"</q>";
        break;
      case "samp":
        //* [samp content] samp。XHTML1.1のsampと同じ
        if(args.length==1)return "<samp>"~args[0] ~"</samp>";
        break;
      case "var":
        //* [var content] 変数。XHTML1.1のvarと同じ
        if(args.length==1)return "<var>"~args[0] ~"</var>";
        break;
      case "blockquote":
        //* [blockquote contents] 引用ブロック。XHTML1.1のblockquoteと同じ
        if(args.length==1)return "<blockquote>"~args[0] ~"</blockquote>";
        //* [blockquote contents,title] 引用ブロック。XHTML1.1のblockquoteと同じ
        if(args.length==2)return "<blockquote title=\""~ArgConv.attrEscape(args[1] )~"\">"~args[0] ~"</blockquote>";
        //* [blockquote contents,title,uri] 引用ブロック。XHTML1.1のblockquoteと同じ
        if(args.length==3)return "<blockquote title=\""~ArgConv.attrEscape(args[1] )~"\" cite=\""~ArgConv.hrefTargetEscape(args[2] )~"\">"~args[0] ~"</blockquote>";
        break;
      case "rem":
        //* [rem contents] コメント
        if(args.length==1)return "";
        break;
      case "pre":
        //* [pre content] 文章以外のテキスト。XHTML1.1のpreと同じ
        if(args.length==1)return "<pre>"~args[0] ~"</pre>";
        break;
      default:
    }+/
    return "Error: Invalid Command or Args or Prefix("~name~":"~.toString(args.length)~")";
  }
}
